// async 用于申明一个 function 是异步的，而 await 用于等待一个异步方法执行完成。
// async 是一个修饰符，async 定义的函数会默认的返回一个Promise对象resolve的值，
// 因此对async函数可以直接进行then操作,返回的值即为then方法的传入函数

// async 函数返回的是一个 Promise 对象。async 函数（包含函数语句、函数表达式、Lambda表达式）
// 会返回一个 Promise 对象，如果在函数中 return 一个直接量，async 会把这个直接量
// 通过 Promise.resolve() 封装成 Promise 对象。


// await 是个运算符，用于组成表达式，await 表达式的运算结果取决于它等的东西。
// 如果它等到的是一个 Promise 对象，等 Promise 对象 resolve，
// 然后得到 resolve 的值，作为 await 表达式的运算结果。
// sync 函数调用不会造成阻塞，它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。

// async/await 的优势在于处理 then 链：
//      单一的 Promise 链并不能发现 async/await 的优势，
// 但是，如果需要处理由多个 Promise 组成的 then 链的时候，优势就能体现出来了
// （很有意思，Promise 通过 then 链来解决多层回调的问题，现在又用 async/await 来进一步优化它）。


function takeLongTime(n) {
    return new Promise(resolve => {
        setTimeout(() => resolve(n + 200), n);
    });
}

// 在 ` ` 中可以使用 ${ }直接把变量与字符串拼接起来

function step1(n) {
    console.log(`step1 with ${n}`);
    return takeLongTime(n);
}

function step2(n) {
    console.log(`step2 with ${n}`);
    return takeLongTime(n);
}

function step3(n) {
    console.log(`step3 with ${n}`);
    return takeLongTime(n);
}



function doIt() {
    console.time("doIt");
    const time1 = 300;
    step1(time1)
        .then(time2 => step2(time2))
        .then(time3 => step3(time3))
        .then(result => {
            console.log(`Promise result is ${result}`);
            console.timeEnd("doIt");
        });
}

doIt();

// 用 async/await 来实现

function step01(n) {
    console.log(`step01 with ${n}`);
    return takeLongTime(n);
}

function step02(m,n) {
    console.log(`step02 with ${m} and ${n}`);
    return takeLongTime(m+n);
}

function step03(k,m,n) {
    console.log(`step03 with ${k} and ${m} and ${n}`);
    return takeLongTime(k+m+n);
}
async function doIt2() {
    console.time("doIt2");
    const time1 = 300;
    const time2 = await step01(time1);
    const time3 = await step02(time1,time2);
    const result = await step03(time1,time2,time3);
    console.log(`async result is ${result}`);
    console.timeEnd("doIt2");
}

doIt2();